import { Injectable } from '@nestjs/common';
import * as crypto from 'crypto';

@Injectable()
export class WeChatPayService {
  private readonly appId: string;
  private readonly mchId: string;
  private readonly apiKey: string;
  private readonly notifyUrl: string;

  constructor() {
    this.appId = process.env.WECHAT_APP_ID || '';
    this.mchId = process.env.WECHAT_MCH_ID || '';
    this.apiKey = process.env.WECHAT_API_KEY || '';
    this.notifyUrl = process.env.WECHAT_NOTIFY_URL || '';
  }

  /**
   * 生成微信支付订单
   * @param orderId 订单ID
   * @param amount 金额（分）
   * @param description 商品描述
   * @param openid 用户openid（JSAPI支付需要）
   * @returns 支付参数
   */
  async createOrder(orderId: string, amount: string, description: string, openid?: string) {
    const nonceStr = this.generateNonceStr();
    const timestamp = Math.floor(Date.now() / 1000).toString();
    
    // 构建参数对象，处理可选的openid字段
    const params: Record<string, string> = {
      appid: this.appId,
      mch_id: this.mchId,
      nonce_str: nonceStr,
      body: description,
      out_trade_no: orderId,
      total_fee: amount,
      spbill_create_ip: '127.0.0.1',
      notify_url: this.notifyUrl,
      trade_type: openid ? 'JSAPI' : 'APP',
    };
    
    // 如果提供了openid，则添加到参数中
    if (openid) {
      params.openid = openid;
    }

    // 生成签名
    const sign = this.generateSign(params);
    
    return {
      appId: this.appId,
      partnerId: this.mchId,
      prepayId: 'prepay_id_placeholder', // 实际应该从微信接口获取
      nonceStr,
      timeStamp: timestamp,
      sign,
    };
  }

  /**
   * 处理微信支付回调
   * @param xmlData 微信回调的XML数据
   */
  async handlePaymentNotification(xmlData: string) {
    // 解析XML数据
    // 验证签名
    // 更新订单状态
    // 返回处理结果
    return { success: true };
  }

  /**
   * 生成随机字符串
   * @param length 字符串长度
   * @returns 随机字符串
   */
  private generateNonceStr(length: number = 32): string {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i < length; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
  }

  /**
   * 生成签名
   * @param params 参数对象
   * @returns 签名
   */
  private generateSign(params: Record<string, string>): string {
    // 按键名ASCII码升序排序
    const sortedKeys = Object.keys(params).sort();
    const stringA = sortedKeys
      .map(key => `${key}=${params[key]}`)
      .join('&');
    
    // 拼接API密钥
    const stringSignTemp = `${stringA}&key=${this.apiKey}`;
    
    // MD5加密并转大写
    return crypto
      .createHash('md5')
      .update(stringSignTemp)
      .digest('hex')
      .toUpperCase();
  }
}